package ma.ensao.evalmetrics.controller.metrics;

import japa.parser.ParseException;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import ma.ensao.evalmetrics.controller.CaracteristiquesManager;
import ma.ensao.evalmetrics.controller.MetriquesManager;
import ma.ensao.evalmetrics.controller.ProprieteManager;
import ma.ensao.evalmetrics.controller.SubcaracManager;
import ma.ensao.evalmetrics.model.Caracteristiques;
import ma.ensao.evalmetrics.model.Metriques;
import ma.ensao.evalmetrics.model.Propriete;
import ma.ensao.evalmetrics.model.Result;
import ma.ensao.evalmetrics.model.ResultClasse;
import ma.ensao.evalmetrics.model.ResultMethod;
import ma.ensao.evalmetrics.model.Stat;
import ma.ensao.evalmetrics.model.Subcarac;
/*
* Outil pour tester que QDox peut analyser le code source Java.
*/
public class QDoxTester {
	List<String> pathjava = new ArrayList<String>();

	int k = 0;
	String path;
	int nbclasses = 0;

	private double ahf = 0;
	private double apf = 0;
	private double cloc = 0;
	private double loc = 0;
	private double mhf = 0;
	private int mhfMethods = 0;
	private double msf = 0;
	private int msfMethods = 0;
	private double mpf = 0;
	private int mpfMethods = 0;
	private double npm = 0;
	private int npmMethods = 0;
	private double noc = 0;
	private double rfc = 0;
	private double pof = 0;
	private double abs = 0;
	private int notAbs = 0;
	private double tcc = 0;
	private double mpc = 0;
	private double noi=0;
	
	private double totaldit=0;
	private double totalce=0;
	private double totalca=0;
	private double totalwmc=0;
	private double totali=0;

	
	
	
	private int totalMethodes = 0;
	private int totalAttributs = 0;
	private int totalClasses = 0;
	
	private ComponentsManager cmpmanager = new ComponentsManager();
	private AHFManager ahfmanager = new AHFManager();
	private APFManager apfmanager = new APFManager();
	private CLOCManager clocmanager = new CLOCManager();
	private LOCManager locmanager = new LOCManager();
	private MHFManager mhfmanager = new MHFManager();
	private MSFManager msfmanager = new MSFManager();
	private MPFManager mpfmanager = new MPFManager();
	private NPMManager npmmanager = new NPMManager();
	private NOCManager nocmanager = new NOCManager();
	private POFManager pofmanager = new POFManager();
	private RFCManager rfcmanager = new RFCManager();
	private WMCManager wmcmanager = new WMCManager();
	private TCCManager tccmanager = new TCCManager();
	private MPCManager mpcmanager = new MPCManager();
	private NOIManager noimanager = new NOIManager();
	private AbstractionManager abss = new AbstractionManager();
	private MethodMetrics methods;
	private ClassMetrics classes;
	//private 
	private Metriques parametres;
	private Caracteristiques carac;
	private Subcarac sub;
	Propriete propriete = new Propriete();
	private Result result = new Result();
	private Stat stat = new Stat();
	private List<ResultMethod> resultMethods=new ArrayList<ResultMethod>(); 
	private List<ResultClasse> resultClasses = new ArrayList<ResultClasse>(); 

	
	
	public List<ResultClasse> getResultClasses() {
		return resultClasses;
	}

	public void setResultClasses(List<ResultClasse> resultClasses) {
		this.resultClasses = resultClasses;
	}

	public List<ResultMethod> getResultMethods() {
		return resultMethods;
	}

	public void setResultMethods(List<ResultMethod> resultMethods) {
		this.resultMethods = resultMethods;
	}

	public Result getResult() {
		return result;
	}

	public void setResult(Result result) {
		this.result = result;
	}

	public Propriete getPropriete() {
		return propriete;
	}

	public void setPropriete(Propriete propriete) {
		this.propriete = propriete;
	}


	private Calcule calcule = new Calcule();

	public Caracteristiques getCarac() {
		return carac;
	}

	public void setCarac(Caracteristiques carac) {
		this.carac = carac;
	}

	public Subcarac getSub() {
		return sub;
	}

	public void setSub(Subcarac sub) {
		this.sub = sub;
	}

	public Metriques getParametres() {
		return parametres;
	}

	public void setParametres(Metriques parametres) {
		this.parametres = parametres;
	}

	private MetriquesManager metriquesmanager = new MetriquesManager();
	private ProprieteManager proprietemanager = new ProprieteManager();
	private CaracteristiquesManager caracteristiques = new CaracteristiquesManager();
	private SubcaracManager subcarac = new SubcaracManager();

	public List<String> getpathjava() {
		return pathjava;
	}

	public void setpathjava(List<String> pathjava) {
		this.pathjava = pathjava;
	}

	public List<String> action(File file) {

		File[] files = file.listFiles();

		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory() == true) {
					action(files[i]);
				} else {
					if (files[i].getName().endsWith(".java")) {
						pathjava.add(files[i].getAbsolutePath() );
					}

				}

			}
		}
		return pathjava;

	}

	public List<String> actionarbo(File file) {
		File[] files = file.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory() == true) {
					path = files[i].getAbsolutePath();
					actionarbo(files[i]);
				} else {
					if (files[i].getName().endsWith(".java")) {
						pathjava.add(path + "\\" + files[i].getName());
						nbclasses++;
						try {

							methods = new MethodMetrics();
							classes = new ClassMetrics();
							List<ResultMethod> fileMethodList = methods.read(files[i]);
							List<ResultClasse> fileClassList = classes.read(files[i]);
							resultMethods.addAll(fileMethodList);
							int wmc =0;
							for(int j=0;j<fileClassList.size();j++){
								wmc=0;
								for(ResultMethod m:fileMethodList){
									if(fileClassList.get(j).getClasseName().equals(m.getClasse())){
										wmc += m.getVg();
									}
								}
								fileClassList.get(j).setWmc(wmc);
								totaldit += fileClassList.get(j).getDit();
								totalce += fileClassList.get(j).getCe();
								totalca += fileClassList.get(j).getCa();
								totali += fileClassList.get(j).getInstab();
								totalwmc += wmc;
								
								
								
							}
							
							resultClasses.addAll(fileClassList);
							ahf = ahf + ahfmanager.read(files[i]).getNmbre();
							apf = apf + apfmanager.read(files[i]).getNmbre();
							cloc = cloc + clocmanager.read(files[i]).getCmt();
							loc = loc + locmanager.read(files[i]).getLine();
							mhf = mhf + mhfmanager.read(files[i]).getNmbre();
							mhfMethods = mhfMethods + mhfmanager.read(files[i]).getNbMethods();
							msf = msf + msfmanager.read(files[i]).getNmbre();
							msfMethods = msfMethods + msfmanager.read(files[i]).getNbMethods();
							mpf = mpf + mpfmanager.read(files[i]).getNmbre();
							mpfMethods = mpfMethods + mpfmanager.read(files[i]).getNbMethods();
							npm = npm + npmmanager.read(files[i]).getNmbre();
							npmMethods = npmMethods + npmmanager.read(files[i]).getNbMethods();
							noi = noi + noimanager.read(files[i]).getInterf();
							totalClasses = totalClasses + cmpmanager.read(files[i]).getNbClasses();
							totalMethodes = totalMethodes + cmpmanager.read(files[i]).getNbMethodes();
							totalAttributs = totalAttributs + cmpmanager.read(files[i]).getNbAttributs();
							
							noc = noc + nocmanager.read(files[i]).getCmt();
							pofmanager.pof(files[i]);
							System.out.println("Qdox  "+pofmanager.getResultat());
							pof = pof + pofmanager.getResultat();
							System.out.println("Qdoxn AFTER  "+pofmanager.getResultat());
							rfc = rfc + rfcmanager.read(files[i]).getNmbre();
							wmc = wmc + wmcmanager.read(files[i]).getNbrecycl();
							abss.abs(files[i]);
							abs = abs + abss.getAbsClasses();
							notAbs = notAbs + abss.getNonAbs();
							System.out.println(files[i].getPath());
							tcc = tcc + tccmanager.read(files[i]).getNmbre();
							try {
								mpc = mpc
										+ mpcmanager.read(files[i]).getNmbre();
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							System.out.println("test DO YOU" + ahf);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}
			}

		} else {
			System.out.println("Hello I'm QDox");
			pathjava.add(file.getAbsolutePath());
			nbclasses++;
			try {
				methods = new MethodMetrics();
				classes = new ClassMetrics();
				List<ResultMethod> fileMethodList = methods.read(file);
				List<ResultClasse> fileClassList = classes.read(file);
				resultMethods.addAll(fileMethodList);
				int wmc =0;
				for(int j=0;j<fileClassList.size();j++){
					wmc=0;
					for(ResultMethod m:fileMethodList){
						if(fileClassList.get(j).getClasseName().equals(m.getClasse())){
							wmc += m.getVg();
						}
					}
					fileClassList.get(j).setWmc(wmc);
					totaldit += fileClassList.get(j).getDit();
					totalce += fileClassList.get(j).getCe();
					totalca += fileClassList.get(j).getCa();
					totali += fileClassList.get(j).getInstab();
					totalwmc += wmc;
				}
				
				resultClasses.addAll(fileClassList);
				ahf = ahf + ahfmanager.read(file).getNmbre();
				apf = apf + apfmanager.read(file).getNmbre();
				cloc = cloc + clocmanager.read(file).getCmt();
				loc = loc + locmanager.read(file).getLine();
				mhf = mhf + mhfmanager.read(file).getNmbre();
				mhfMethods = mhfMethods + mhfmanager.read(file).getNbMethods();
				msf = msf + msfmanager.read(file).getNmbre();
				msfMethods = msfMethods + msfmanager.read(file).getNbMethods();
				mpf = mpf + mpfmanager.read(file).getNmbre();
				mpfMethods = mpfMethods + mpfmanager.read(file).getNbMethods();
				npm = npm + npmmanager.read(file).getNmbre();
				npmMethods = npmMethods + npmmanager.read(file).getNbMethods();
				noc = noc + nocmanager.read(file).getCmt();
				noi = noi + noimanager.read(file).getInterf();
				pofmanager.pof(file);
				pof = pof + pofmanager.getResultat();
				rfc = rfc + rfcmanager.read(file).getNmbre();
				abss.abs(file);
				abs = abs + abss.getAbsClasses();
				notAbs = notAbs + abss.getNonAbs();
				tcc = tcc + tccmanager.read(file).getNmbre();
				totalClasses = totalClasses + cmpmanager.read(file).getNbClasses();
				totalMethodes = totalMethodes + cmpmanager.read(file).getNbMethodes();
				totalAttributs = totalAttributs + cmpmanager.read(file).getNbAttributs();

				try {
					mpc = mpc + mpcmanager.read(file).getNmbre();
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("done");
		}
		System.out.println("FIN DE CALCUL DES METRIQUES");

		return pathjava;

	}

	public void metric(Long Id) {
		System.out.println("NEW METRIC");
		
		ahf = ahf / totalAttributs;
		ahf = new BigDecimal(ahf ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		apf = apf / nbclasses;
		mhf = (double) mhfMethods / (double)totalMethodes;
		mhf = new BigDecimal(mhf ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		msf = (double) msfMethods / (double)totalMethodes;
		msf = new BigDecimal(msf ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		mpf = (double) mpfMethods / (double)totalMethodes;
		mpf = new BigDecimal(mpf ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		npm = (double) npmMethods / (double)totalMethodes;
		npm = new BigDecimal(npm ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		noc = noc / nbclasses;
		
		totaldit=totaldit/totalClasses;
		totaldit = new BigDecimal(totaldit ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		totalce=totalce/totalClasses;
		totalce = new BigDecimal(totalce ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		totalca=totalca/totalClasses;
		totalca = new BigDecimal(totalca ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		totalwmc=totalwmc/totalClasses;
		totalwmc = new BigDecimal(totalwmc ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		totali=totali/totalClasses;
		totali = new BigDecimal(totali ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		
		double noi1;
		//rfc = rfc / nbclasses;
		System.out.println("rfcccccc"+rfc);
		pof = pof / nbclasses;
		double abstr = abs / (abs+notAbs);
		tcc = tcc / nbclasses;
		mpc = mpc / nbclasses;
		noi1 = noi / nbclasses;
		
		double totalD = 0,D=0;
		for(int i=0;i<resultClasses.size();i++){
			D=resultClasses.get(i).getInstab()+abstr-1;
			resultClasses.get(i).setD(D);
			totalD +=D;

		}
		totalD = totalD / (double) totalClasses;
		
		result.setD(totalD);
		result.setAbs(abstr);
		result.setAHF(ahf);
		result.setAPF(apf);
		result.setCLOC(cloc);
		result.setCyclo(totalwmc);
		result.setLOC(loc);
		result.setMHF(mhf);
		result.setMSF(msf);
		result.setNPM(npm);
		result.setMPC(mpc);
		result.setMPF(mpf);
		result.setNOC(noc);
		result.setNOM(totalMethodes);
		result.setPOF(pof);
		result.setRFC(rfc);
		result.setTCC(tcc);
		result.setI(totali);
		result.setCa(totalca);
		result.setCe(totalce);
		result.setDit(totaldit);
		result.setNOI(noi1);
		result.setClasses(totalClasses);
		stat.setNbMHF(mhfMethods);
		stat.setNbMPF(mpfMethods);
		stat.setNbMSF(msfMethods);
		stat.setNbNPM(npmMethods);
		stat.setNbAtrributs(totalAttributs);
		stat.setNbMethods(totalMethodes);
		stat.setNbClasses(totalClasses);
		stat.setNbFiles(nbclasses);
	
		parametres = metriquesmanager.list(Id).get(0);
		carac = caracteristiques.list(Id).get(0);
		sub = subcarac.list(Id).get(0);
		propriete = proprietemanager.list(Id).get(0);
		System.out.println("NOW LES SOMMES ");
		parametres = calcule.calculMetrique(parametres, result);
		propriete = calcule.calculPropriete(propriete);
		sub = calcule.calculSubcarac(sub);
		carac = calcule.calculCaracteristiques(carac);

	}

	public Stat getStat() {
		return stat;
	}

	public void setStat(Stat stat) {
		this.stat = stat;
	}

}